/* SPDX-License-Identifier: BSD-3-Clause */
/* Copyright (c) 2023, Unikraft GmbH and The Unikraft Authors.
 * Licensed under the BSD-3-Clause License (the "License").
 * You may not use this file except in compliance with the License.
 */
#include <uk/config.h>
#include <uk/libid/info.h>
#include <uk/arch/types.h>

#define RECORD(type, data)				  \
	.align 1					; \
1:	.__u16 type			/* type */	; \
	.__u32 2f - 1b			/* len */	; \
	data				/* data[] */	; \
2:	.align 1

.pushsection .uk_libinfo, "a"
	.align 1
3:	.__u32 4f - 3b			/* len */
	.__u16 UKLI_LAYOUT		/* version */

#if __GLOBALINFO__
	/* Only one global header per unikernel is generated */
	/* NOTE: Global metadata do not have a libname record */
#if CONFIG_LIBUKLIBID_INFO_UKFULLVERSION
	RECORD(UKLI_REC_UKFULLVERSION, .asciz STRINGIFY(UK_FULLVERSION))
#else /* !CONFIG_LIBUKLIBID_INFO_UKFULLVERSION */
	RECORD(UKLI_REC_UKVERSION,     .asciz STRINGIFY(UK_VERSION))
#endif /* !CONFIG_LIBUKLIBID_INFO_UKFULLVERSION */
#if CONFIG_LIBUKLIBID_INFO_UKCODENAME
	RECORD(UKLI_REC_UKCODENAME,    .asciz STRINGIFY(UK_CODENAME))
#endif /* CONFIG_LIBUKLIBID_INFO_UKCODENAME */
#if CONFIG_LIBUKLIBID_INFO_COMPILER
	RECORD(UKLI_REC_COMPILER,
	       .asciz STRINGIFY(__LIBUKLIBID_COMPILER__))
#endif /* CONFIG_LIBUKLIBID_INFO_COMPILER */
#if CONFIG_LIBUKLIBID_INFO_COMPILEDATE
	RECORD(UKLI_REC_COMPILEDATE,
	       .asciz STRINGIFY(UK_UTCDATE))
#endif /* CONFIG_LIBUKLIBID_INFO_COMPILEDATE */
#if CONFIG_LIBUKLIBID_INFO_UKCONFIGGZ
	RECORD(UKLI_REC_UKCONFIGGZ,    .incbin STRINGIFY(UK_CONFIGGZINC))
#endif /* CONFIG_LIBUKLIBID_INFO_UKCONFIGGZ */

#else /* !__GLOBALINFO__ */
	/* Records per library */
	/* NOTE: The libname record is mandatory */
	RECORD(UKLI_REC_LIBNAME,       .asciz STRINGIFY(__LIBNAME__))
#if CONFIG_LIBUKLIBID_INFO_LIB_UKVERSION
#if CONFIG_LIBUKLIBID_INFO_LIB_UKFULLVERSION
	RECORD(UKLI_REC_UKFULLVERSION, .asciz STRINGIFY(UK_FULLVERSION))
#else /* !CONFIG_LIBUKLIBID_INFO_LIB_UKVERSION */
	RECORD(UKLI_REC_UKVERSION,     .asciz STRINGIFY(UK_VERSION))
#endif /* !CONFIG_LIBUKLIBID_INFO_LIB_UKVERSION */
#endif /* CONFIG_LIBUKLIBID_INFO_LIB_UKVERSION */
#if CONFIG_LIBUKLIBID_INFO_LIB_UKCODENAME
	RECORD(UKLI_REC_UKCODENAME,    .asciz STRINGIFY(UK_CODENAME))
#endif /* CONFIG_LIBUKLIBID_INFO_LIB_UKCODENAME */
#if CONFIG_LIBUKLIBID_INFO_LIB_COMPILER
	RECORD(UKLI_REC_COMPILER,
	       .asciz STRINGIFY(__LIBUKLIBID_COMPILER__))
#endif /* CONFIG_LIBUKLIBID_INFO_COMPILER */
#if CONFIG_LIBUKLIBID_INFO_LIB_COMPILEDATE
	RECORD(UKLI_REC_COMPILEDATE,
	       .asciz STRINGIFY(__LIBUKLIBID_UTCDATE__))
#endif /* CONFIG_LIBUKLIBID_INFO_COMPILEDATE */
#if CONFIG_OPTIMIZE_PIE
#define CO_FLAG_PIE UKLI_REC_CO_PIE
#else /* !CONFIG_OPTIMIZE_PIE */
#define CO_FLAG_PIE 0x0
#endif /* !CONFIG_OPTIMIZE_PIE */
#if CONFIG_OPTIMIZE_DEADELIM
#define CO_FLAG_DCE UKLI_REC_CO_DCE
#else /* !CONFIG_OPTIMIZE_DEADELIM */
#define CO_FLAG_DCE 0x0
#endif /* !CONFIG_OPTIMIZE_DEADELIM */
#if CONFIG_OPTIMIZE_LTO
#define CO_FLAG_LTO UKLI_REC_CO_LTO
#else /* !CONFIG_OPTIMIZE_LTO */
#define CO_FLAG_LTO 0x0
#endif /* !CONFIG_OPTIMIZE_LTO */
	RECORD(UKLI_REC_COMPILEOPTS,   .__u32 ((CO_FLAG_PIE | \
						CO_FLAG_DCE | \
						CO_FLAG_LTO)))
#endif /* !__GLOBALINFO__ */

#if CONFIG_LIBUKLIBID_INFO_COMPILEDBY_HOST
	RECORD(UKLI_REC_COMPILEDBY,
	       .asciz STRINGIFY(__LIBUKLIBID_COMPILEDBY_HOST__))
#endif /* CONFIG_LIBUKLIBID_INFO_COMPILEDBY_HOST */
#if CONFIG_LIBUKLIBID_INFO_COMPILEDBY_CUSTOM
	RECORD(UKLI_REC_COMPILEDBY,
	       .asciz CONFIG_LIBUKLIBID_INFO_COMPILEDBY_CUSTOM_TEXT)
#endif /* CONFIG_LIBUKLIBID_INFO_COMPILEDBY_CUSTOM */
#if CONFIG_LIBUKLIBID_INFO_COMPILEDBYASSOC
	RECORD(UKLI_REC_COMPILEDBYASSOC,
	       .asciz CONFIG_LIBUKLIBID_INFO_COMPILEDBYASSOC_TEXT)
#endif /* CONFIG_LIBUKLIBID_INFO_COMPILEDBYASSOC */

4:	.align 1
.popsection
